


#ifndef WXFLATNOTEBOOK_H
#define WXFLATNOTEBOOK_H

#include <wx/wxFlatNotebook/wxFlatNotebookSDK.h>
#include <wx/wx.h>
#include <wx/frame.h>
#include <wx/dynarray.h>

#ifdef __WXMSW__
#ifdef _DEBUG
#define DEBUG_NEW new(_NORMAL_BLOCK ,__FILE__, __LINE__)
#else
#define DEBUG_NEW new
#endif
#endif 

#include <wx/dcbuffer.h>
#include <wx/dataobj.h>
#include <wx/dnd.h>

#include <wx/wxFlatNotebook/wxFNBDropTarget.h>

class wxPageContainer;

#ifndef M_PI
#define M_PI 3.14159265358979
#endif

#ifndef wxFNB_HEIGHT_SPACER
#define wxFNB_HEIGHT_SPACER 10
#endif

// forward declerations
class wxFNBRenderer;
class wxFNBRendererDefault;
class wxFNBRendererVC71;
class wxFNBRendererVC8;
class wxTabNavigatorWindow;
class wxMenu;

#define FNB_MIN(a, b) ((a > b) ? b : a)

WX_DECLARE_USER_EXPORTED_OBJARRAY(wxBitmap, wxFlatNotebookImageList, WXDLLIMPEXP_FNB);
WX_DECLARE_USER_EXPORTED_OBJARRAY(wxWindow*, wxWindowPtrArray, WXDLLIMPEXP_FNB);

#define wxFNB_DEFAULT_STYLE				wxFNB_MOUSE_MIDDLE_CLOSES_TABS
#define wxFNB_VC71						0x00000001
#define wxFNB_FANCY_TABS				0x00000002
#define wxFNB_TABS_BORDER_SIMPLE		0x00000004
#define wxFNB_NO_X_BUTTON				0x00000008
#define wxFNB_NO_NAV_BUTTONS			0x00000010
#define wxFNB_MOUSE_MIDDLE_CLOSES_TABS	0x00000020
#define wxFNB_BOTTOM					0x00000040
#define wxFNB_NODRAG					0x00000080
#define wxFNB_VC8						0x00000100
#define wxFNB_X_ON_TAB					0x00000200
#define wxFNB_BACKGROUND_GRADIENT		0x00000400
#define wxFNB_COLORFUL_TABS				0x00000800
#define wxFNB_DCLICK_CLOSES_TABS		0x00001000
#define wxFNB_SMART_TABS				0x00002000
#define wxFNB_DROPDOWN_TABS_LIST		0x00004000
#define wxFNB_ALLOW_FOREIGN_DND			0x00008000
#define wxFNB_FF2						0x00010000	
#define wxFNB_CUSTOM_DLG				0x00020000	
#define wxFNB_BOTTOM_LINE_COLOR_CHANGE	0x00100000
#define wxFNB_INVERSE_COLOR_LINE_VC8	0x00200000
#define wxFNB_PREVIEW_SELECT_TAB		0x00400000

#define VERTICAL_BORDER_PADDING			4
#define BUTTON_SPACE					16
#define VC8_SHAPE_LEN					16
#define MASK_COLOR wxColor(0, 128, 128)

enum wxCustomizeDlgOptions {
	wxFNB_CUSTOM_TAB_LOOK		= 0x00000001,
	wxFNB_CUSTOM_ORIENTATION	= 0x00000002,
	wxFNB_CUSTOM_FOREIGN_DRAG	= 0x00000004,
	wxFNB_CUSTOM_LOCAL_DRAG		= 0x00000008,
	wxFNB_CUSTOM_CLOSE_BUTTON	= 0x00000010,
	wxFNB_CUSTOM_ALL			= wxFNB_CUSTOM_TAB_LOOK | 
								  wxFNB_CUSTOM_ORIENTATION |
								  wxFNB_CUSTOM_FOREIGN_DRAG |
								  wxFNB_CUSTOM_LOCAL_DRAG |
								  wxFNB_CUSTOM_CLOSE_BUTTON 
};



class WXDLLIMPEXP_FNB wxFlatNotebook : public wxPanel
{
public:


	wxFlatNotebook() 
	{ Init(); }


	
	wxFlatNotebook(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = wxT("Flat Notebook"));

	
	bool Create(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = wxT("Flat Notebook"));


	virtual ~wxFlatNotebook(void);

	
    static void CleanUp ();

	
	void AdvanceSelection(bool bForward);


	
	bool AddPage(wxWindow* windows, const wxString& caption, const bool selected = false, const int imgindex = -1);


	
	bool InsertPage(size_t index, wxWindow* page, const wxString& text, bool select = false, const int imgindex = -1);

	
	void SetSelection(size_t page);

	
	void DeletePage(size_t page, bool notify = true);


	bool DeleteAllPages();


	int  GetPageCount() const;


	wxWindow * GetCurrentPage() const;


	
	wxWindow * GetPage(size_t page) const;

	
	int GetPageIndex(wxWindow* win) const;


	int GetSelection() const;

	
	int GetPreviousSelection() const;

	const wxArrayInt &GetBrowseHistory() const;


	
	bool GetPageShapeAngle(int page_index, unsigned int * result);

	
	void SetPageShapeAngle(int page_index, unsigned int angle);

	
	void SetAllPagesShapeAngle(unsigned int angle);


	wxSize GetPageBestSize();


	
	bool SetPageText(size_t page, const wxString& text);

	
	bool RemovePage(size_t page, bool notify = true);


	
	void SetPadding(const wxSize& padding);

	
	virtual void SetWindowStyleFlag(long style);


	
	void SetRightClickMenu(wxMenu* menu);

	
	wxString GetPageText(size_t page);

	
	void SetPageImageIndex(size_t page, int imgindex);

	
	int GetPageImageIndex(size_t page);

	
	void SetGradientColors(const wxColour& from, const wxColour& to, const wxColour& border);

	
	void SetGradientColorFrom(const wxColour& from);


	
	void SetGradientColorTo(const wxColour& to);

	
	void SetGradientColorBorder(const wxColour& border);
	

	
	void SetPreviewSelectColor(const wxColour& select);
	

	
	void SetDisableTextColour(const wxColour& disable);


	
	void SetImageList(wxFlatNotebookImageList * imglist);


	wxFlatNotebookImageList * GetImageList();

	
	wxDragResult OnDropTarget(wxCoord x, wxCoord y, int nTabPage, wxWindow * wnd_oldContainer);


	
	void Enable(size_t page, bool enabled);


	
	bool GetEnabled(size_t page);



	bool SetFont(const wxFont& font);


	wxFont& GetFont();



	
	void SetActiveTabTextColour(const wxColour& textColour);


	const wxColour& GetGradientColorFrom();


	const wxColour& GetGradientColorTo();


	const wxColour& SetGradientColorBorder();


	const wxColour& GetActiveTabTextColour();


	const wxColour& GetNonActiveTabTextColour();


	void SetNonActiveTabTextColour(const wxColour& color);


	wxPanel* GetTabArea() { return (wxPanel*)m_pages; }


	const wxColour& GetTabAreaColour();


	void SetTabAreaColour(const wxColour& color);


	const wxColour& GetActiveTabColour();


	void SetActiveTabColour(const wxColour& color);

	
	int GetPadding() { return m_nPadding; }

	
	void SetCustomizeOptions(long options);
	
	
	long GetCustomizeOptions() const;
	

	void SetForceSelection(bool force) { m_bForceSelection = force; }
	bool GetForceSelection() { return m_bForceSelection; }
	wxWindowPtrArray& GetWindows() { return m_windows; }
	wxPageContainer *GetPages() { return m_pages; }
	wxBoxSizer* GetMainSizer() { return m_mainSizer; }

protected:

	virtual void Init();
	wxPageContainer *m_pages;

private:




	bool m_bForceSelection;

	wxBoxSizer* m_mainSizer;


	wxWindowPtrArray m_windows;
	wxFNBDropTarget<wxFlatNotebook> *m_pDropTarget;
	int m_nFrom;
	int m_nPadding;
	wxTabNavigatorWindow *m_popupWin;
	bool m_sendPageChangeEvent; 
	DECLARE_DYNAMIC_CLASS(wxFlatNotebook)
	DECLARE_EVENT_TABLE()
	void OnNavigationKey(wxNavigationKeyEvent& event);
};


class WXDLLIMPEXP_FNB wxPageInfo
{
private:


	wxString m_strCaption;


	wxPoint m_pos;


	wxSize  m_size;


	wxRegion m_region;


	unsigned int m_TabAngle;


	int m_ImageIndex;


	bool m_bEnabled;


	wxRect m_xRect;


	wxColor m_color;

public:


	wxPageInfo(): m_strCaption(wxEmptyString), m_TabAngle(0), m_ImageIndex(-1), m_bEnabled(true){};

	
	wxPageInfo(const wxString& caption, int imgindex) :
	m_strCaption(caption), m_pos(-1, -1), m_size(-1, -1), m_TabAngle(0), m_ImageIndex(imgindex), m_bEnabled(true){}

	~wxPageInfo(){};


	
	void SetCaption(wxString value) {m_strCaption = value;}


	wxString GetCaption() {return m_strCaption;}


	
	void SetPosition(wxPoint value) {m_pos = value;}


	const wxPoint & GetPosition() {return m_pos;}


	
	void SetSize(wxSize value) {m_size = value;}


	const wxSize & GetSize() {return m_size;}


	
	void SetTabAngle(unsigned int value) {m_TabAngle = FNB_MIN((unsigned int)(45), (unsigned int)(value));}


	unsigned int GetTabAngle() {return m_TabAngle;}

	
	void SetImageIndex(int value) {m_ImageIndex = value;}


	int GetImageIndex() {return m_ImageIndex;}


	bool GetEnabled() { return m_bEnabled; }


	
	void Enable(bool enabled) { m_bEnabled = enabled; }


	
	void SetRegion(const size_t n, const wxPoint points[]) { m_region = wxRegion(n, points); }


	wxRegion& GetRegion() { return m_region ; }


	
	void SetXRect(const wxRect& xrect) { m_xRect = xrect; }


	wxRect& GetXRect() { return m_xRect; }

	
	wxColor GetColor() { return m_color; }

	
	void SetColor(wxColor& color) { m_color = color; }

};

WX_DECLARE_USER_EXPORTED_OBJARRAY(wxPageInfo, wxPageInfoArray, WXDLLIMPEXP_FNB);

/// Button status
enum
{
	wxFNB_BTN_PRESSED,
	wxFNB_BTN_HOVER,
	wxFNB_BTN_NONE
};

/// Hit Test results
enum
{
	wxFNB_TAB,			
	wxFNB_X,			
	wxFNB_TAB_X,		
	wxFNB_LEFT_ARROW,	
	wxFNB_RIGHT_ARROW,	
	wxFNB_DROP_DOWN_ARROW,
	wxFNB_NOWHERE		
};


class WXDLLIMPEXP_FNB wxPageContainer : public wxPanel
{
protected:

	friend class wxFlatNotebook;
	friend class wxFNBRenderer;
	friend class wxFNBRendererDefault;
	friend class wxFNBRendererVC71;
	friend class wxFNBRendererVC8;
	friend class wxFNBRendererFirefox2;

	wxFlatNotebookImageList * m_ImageList;

public:

	
	wxPageContainer(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0);

	virtual ~wxPageContainer(void);


	
	virtual void SetImageList(wxFlatNotebookImageList * imglist) {m_ImageList = imglist;}


	virtual wxFlatNotebookImageList * GetImageList() {return m_ImageList;}


	
	virtual bool AddPage(const wxString& caption, const bool selected = false, const int imgindex = -1);


	
	virtual bool InsertPage(size_t index, wxWindow* page, const wxString& text, bool select = false, const int imgindex = -1);


	
	virtual void SetSelection(size_t page);


	virtual int GetSelection() { return m_iActivePage; }


	
	virtual void AdvanceSelection(bool bForward);


	virtual size_t GetPageCount() { return m_pagesInfoVec.size(); }


	
	virtual wxString GetPageText(size_t page) { return m_pagesInfoVec[page].GetCaption(); }


	
	virtual bool SetPageText(size_t page, const wxString& text) { m_pagesInfoVec[page].SetCaption(text); return true; }


	
	virtual void SetPageImageIndex(size_t page, int imgindex);

	
	virtual int GetPageImageIndex(size_t page);


	
	virtual void Enable(size_t page, bool enabled);


	
	virtual bool GetEnabled(size_t page);


	bool HasFlag(int flag);

	
	wxPageInfoArray& GetPageInfoVector() { return m_pagesInfoVec; }

	
	const wxColour&  GetGradientColourFrom() const { return m_colorFrom; }

	
	const wxColour&  GetGradientColourTo() const { return m_colorTo; }
	
	const wxColour&  GetBorderColour() const { return m_colorBorder; }

	
	const wxColour&  GetNonoActiveTextColor() const { return m_nonActiveTextColor; }

	
	const wxColour&  GetActiveTabColour() const { return m_activeTabColor; }

	
	int GetPreviousSelection() const;
	
	void DrawDragHint();
	
	
	void SetCustomizeOptions(long options);
	
	
	long GetCustomizeOptions() const;

	DECLARE_EVENT_TABLE()

	virtual void OnPaint(wxPaintEvent& event);
	virtual void OnSize(wxSizeEvent& WXUNUSED(event));
	virtual void OnMouseMove(wxMouseEvent& event);
	virtual void OnLeftDown(wxMouseEvent& event);
	virtual void OnLeftUp(wxMouseEvent& event);
	virtual void OnRightDown(wxMouseEvent& event);
	virtual void OnMiddleDown(wxMouseEvent& event);
	virtual void OnEraseBackground(wxEraseEvent& WXUNUSED(event)) { }
	virtual void OnMouseLeave(wxMouseEvent& event);
	virtual void OnMouseEnterWindow(wxMouseEvent& event);
	virtual void OnLeftDClick(wxMouseEvent &event);
	virtual void OnTabMenuSelection(wxCommandEvent &event);
	virtual void OnShowCustomizeDialog(wxCommandEvent &event);

protected:
	
	void RotateLeft();
	void RotateRight();

	
	void PopupTabsMenu();

	void ClearFlag(int flag);


	bool TabHasImage(int tabIdx);


	virtual bool IsDefaultTabs();


	virtual wxColor GetSingleLineBorderColor();


	virtual bool IsTabVisible(size_t page);


	virtual int HitTest(const wxPoint& pt, wxPageInfo& pageInfo, int &tabIdx);


	virtual void ShowTabTooltip(int tabIdx);


	virtual void DeletePage(size_t page);


	virtual void DeleteAllPages();



	virtual void DoDeletePage(size_t page);


	virtual void DoSetSelection(size_t page);


	virtual int  GetLastVisibleTab();



	virtual int  GetNumTabsCanScrollLeft();


	virtual int GetNumOfVisibleTabs();

	
	virtual wxDragResult OnDropTarget(wxCoord x, wxCoord y, int nTabPage, wxWindow * wnd_oldContainer);

	
	virtual void MoveTabPage(int nMove, int nMoveTo);



	
	virtual bool CanFitToScreen(size_t page);
	
	void PushPageHistory(int page);




	void PopPageHistory(int page);

protected:

	wxPageInfoArray m_pagesInfoVec;
	int m_iActivePage;
	int m_nFrom;


	wxFNBDropTarget<wxPageContainer> *m_pDropTarget;

private:

	wxWindow *m_pParent;


	wxMenu* m_pRightClickMenu;


	wxColour m_colorFrom, m_disableTextColor, m_colorTo, m_colorPreview, m_colorBorder, m_activeTextColor, m_nonActiveTextColor, m_tabAreaColor, m_activeTabColor;



	wxFont m_font;





	int m_nXButtonStatus, m_nLeftButtonStatus, m_nRightButtonStatus, m_nTabXButtonStatus;


	int m_nLeftClickZone;


	wxArrayInt m_history;
	int m_nArrowDownButtonStatus;


	wxMenu *m_customMenu;
	long m_customizeOptions;


	int m_nTabStatus;
	int m_nTabPreviewId;

};


class WXDLLIMPEXP_FNB wxFlatNotebookEvent : public wxNotifyEvent
{
	DECLARE_DYNAMIC_CLASS(wxFlatNotebookEvent)
	size_t sel, oldsel;

public:

	
	wxFlatNotebookEvent(wxEventType commandType = wxEVT_NULL, int winid = 0, int nSel = -1, int nOldSel = -1)
		: wxNotifyEvent(commandType, winid), sel(nSel), oldsel(nOldSel)
	{}

	
	void SetSelection(int s) { sel = s; }

	
	void SetOldSelection(int s) { oldsel = s; }

	int  GetSelection() { return (int)sel; }

	int  GetOldSelection() { return (int)oldsel; }
};

BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_FNB, wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CHANGED, 50000)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_FNB, wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CHANGING, 50001)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_FNB, wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CLOSING, 50002)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_FNB, wxEVT_COMMAND_FLATNOTEBOOK_CONTEXT_MENU, 50003)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_FNB, wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CLOSED, 50004)
END_DECLARE_EVENT_TYPES()

typedef void (wxEvtHandler::*wxFlatNotebookEventFunction)(wxFlatNotebookEvent&);

#define wxFlatNotebookEventHandler(func) \
	(wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxFlatNotebookEventFunction, &func)

#define EVT_FLATNOTEBOOK_PAGE_CHANGED(winid, fn) \
	wx__DECLARE_EVT1(wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CHANGED, winid, wxFlatNotebookEventHandler(fn))

#define EVT_FLATNOTEBOOK_PAGE_CHANGING(winid, fn) \
	wx__DECLARE_EVT1(wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CHANGING, winid, wxFlatNotebookEventHandler(fn))

#define EVT_FLATNOTEBOOK_PAGE_CLOSING(winid, fn) \
	wx__DECLARE_EVT1(wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CLOSING, winid, wxFlatNotebookEventHandler(fn))

#define EVT_FLATNOTEBOOK_CONTEXT_MENU(winid, fn) \
	wx__DECLARE_EVT1(wxEVT_COMMAND_FLATNOTEBOOK_CONTEXT_MENU, winid, wxFlatNotebookEventHandler(fn))

#define EVT_FLATNOTEBOOK_PAGE_CLOSED(winid, fn) \
	wx__DECLARE_EVT1(wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CLOSED, winid, wxFlatNotebookEventHandler(fn))

#endif // WXFLATNOTEBOOK_H
